﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Cesave.Domain.Core;
using Cesave.Domain.PermisosModule.Entities;
using Cesave.Domain.PermisosModule.Resources;

namespace Cesave.Domain.PermisosModule.Contracts.Estados
{
	/// <summary>
	/// 
	/// </summary>
	public class EstadoService
		: IEstadoService
	{
		#region Private properties

		/// <summary>
		/// 
		/// </summary>
		private readonly IEstadoRepository _estadoRepository;

		#endregion

		#region Constructor

		/// <summary>
		/// 
		/// </summary>
		/// <param name="estadoRepository"></param>
		public EstadoService(IEstadoRepository estadoRepository)
		{
			if (estadoRepository == null)
				throw new ArgumentNullException("estadoRepository", Messages.exception_DependenciesAreNotInitialized);
			_estadoRepository = estadoRepository;
		}

		#endregion

		#region IEstadoService Members

		/// <summary>
		/// 
		/// </summary>
		/// <param name="status"></param>
		/// <returns></returns>
		public List<Estado> FindEstadosByStatus(bool status)
		{
			EstadosByStatusSpecification estadosByStatusSpecification = new EstadosByStatusSpecification(status);
			return _estadoRepository.FindEstadosByStatusSpecification(estadosByStatusSpecification)
				.ToList();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public List<Estado> FindAllEstados()
		{
			return _estadoRepository.GetAll()
				.OrderBy(estado => estado.Nombre)
				.ToList();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="estadoGuid"></param>
		/// <returns></returns>
		public Estado FindEstadoByGuid(Guid estadoGuid)
		{
			if (estadoGuid == Guid.Empty)
				throw new InvalidOperationException(Messages.exception_InvalidArgument);
			EstadoByGuidSpecification estadoByIdSpecification = new EstadoByGuidSpecification(estadoGuid);
			return _estadoRepository.FindEstadoByGuidSpecification(estadoByIdSpecification);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="estado"></param>
		public void ChangeEstado(Estado estado)
		{
			if (estado == null)
				throw new ArgumentNullException("estado", Messages.exception_InvalidArgument);
			IUnitOfWork unitOfWork = _estadoRepository.StoreContext;
			_estadoRepository.Modify(estado);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.CommitAndRefreshChanges();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="estado"></param>
		public void ActivateEstado(Estado estado)
		{
			if (estado == null)
				throw new ArgumentNullException("estado", Messages.exception_InvalidArgument);
			estado.Status = true;
			IUnitOfWork unitOfWork = _estadoRepository.StoreContext;
			_estadoRepository.Modify(estado);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.CommitAndRefreshChanges();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="estado"></param>
		public void DeactivateEstado(Estado estado)
		{
			if (estado == null)
				throw new ArgumentNullException("estado", Messages.exception_InvalidArgument);
			estado.Status = false;
			IUnitOfWork unitOfWork = _estadoRepository.StoreContext;
			_estadoRepository.Modify(estado);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.CommitAndRefreshChanges();
			}
		}

		#endregion

		#region IDisposable Members

		public void Dispose()
		{
			if (_estadoRepository != null &&
				_estadoRepository.StoreContext != null)
				_estadoRepository.StoreContext.Dispose();
		}

		#endregion
	}
}
